/**
 * Copyright &copy; 2012-2014 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
 */
package com.xyp.sso.dubbo.util;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.subject.support.DefaultSubjectContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.xyp.sso.entity.SSOShiroUser;
import com.xyp.sso.entity.User;
import com.xyp.sso.redis.RedisSessionDAO;

/**
 * 用户工具类
 *
 * @author 
 */
public class UserUtils {
    private static Logger logger = LoggerFactory.getLogger(UserUtils.class);

    private static final String SesessionIdKey = UserUtils.class.getName() + "_sessionId";
    private static final String SesessionKey = UserUtils.class.getName() + "_session";
    private static final String REQUEST_ADDRESS_KEY = UserUtils.class.getName() + "_requestAddressKey";
    private static final String RULE_LIST_KEY = UserUtils.class.getName() + "_rulelist";
    private static final int RULE_LIST_KEY_EXPIRESECOND = 30 * 60;
    private static ThreadLocal<Map<String, Object>> sessionLocal = new ThreadLocal<Map<String, Object>>();

    private static RedisSessionDAO redisSessionDAO = SpringContextHolder.getBean(RedisSessionDAO.class);

    public static Session getSession() {

        final Object obj = getThreadVar(SesessionKey);
        Session session = (Session) obj;
        if (session != null) {
            return session;
        }
        final String sessionId = (String) getThreadVar(SesessionIdKey);
        session = redisSessionDAO.doReadSession(sessionId);
        if (session != null) {
            storeThreadVar(SesessionKey, session);
            return session;
        }

        try {
            // web access
            final Subject subject = SecurityUtils.getSubject();
            if (subject != null) {
                final Session se = subject.getSession();
                if (se != null) {
                    return se;
                }
            }
        }
        catch (final Exception e) {
            logger.error("获取session出错：", e);
        }
        return null;
    }

    protected static Object getThreadVar(final String key) {
        if (key == null) {
            return null;
        }
        final Map<String, Object> map = sessionLocal.get();
        if (map == null) {
            return null;
        }
        return map.get(key);
    }

    protected static void storeThreadVar(final String key, final Object value) {
        Map<String, Object> map = sessionLocal.get();
        if (map == null) {
            map = new ConcurrentHashMap<String, Object>();
            sessionLocal.set(map);
        }
        if (key != null && value != null) {
            map.put(key, value);
        }
    }

    public static void clearThreadLocal() {
        sessionLocal.remove();
    }

    public static void storeSessionId(final String anId) {
        clearThreadLocal();
        storeThreadVar(SesessionIdKey, anId);
    }

    public static void storeRequestIp(final String anRequstIp) {

        storeThreadVar(REQUEST_ADDRESS_KEY, anRequstIp);
    }

    /**
     * 获取当前用户
     *
     * @return 取不到返回 new User()
     */
    public static User getUser() {
        final SSOShiroUser principal = getPrincipal();
        if (principal != null) {
            return principal.getUser();
        }
        return null;
    }

    /**
     * 获取当前登录者对象
     */
    public static SSOShiroUser getPrincipal() {
        final Session session = UserUtils.getSession();
        if (session != null) {
            final SimplePrincipalCollection col = (SimplePrincipalCollection) session
                    .getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
            if (col != null) {
                return (SSOShiroUser) col.getPrimaryPrincipal();
            }
        }
        return null;
    }
}
